package cuatroenraya.jugadores;
import cuatroenraya.Jugador;


public class JugadorAlumnoG10 extends Jugador{

	private int[][] ponderacionAtaque;
	private int[][] ponderacionDefensa; 
	
	public JugadorAlumnoG10() {
		this.ponderacionAtaque = new int[8][8]; //guarga las ponderaciones para el ataque
		this.ponderacionDefensa = new int[8][8]; //guarda las ponderaciones para la defensa
	}

	@Override
	public int[] jugar(int[][] tablero) {
		int jugada[] = new int[2];
		int max = 0; /* variable entera que va guardando 
		             la m�xima ponderaci�n y se pisa 
		             cada vez que recorre un casillero vac�o*/
		TipoJugadaG10 tipo = null;
		for (int i = 0; i < 8; i++) {
			for (int j = 0; j < 8; j++) {
				if(tablero[i][j]==0){					
					int ataque = this.getPonderacionAtaque(i,j,tablero);					
					this.ponderacionAtaque[i][j] = ataque;
					
					int defensa = this.getPonderacionDefensa(i, j, tablero);
					this.ponderacionDefensa[i][j] = defensa;
					
			
					
					if(ataque >= defensa && (ataque > max || (ataque == max && tipo==TipoJugadaG10.DEFENSA))  ){
					    max = ataque;
						tipo = TipoJugadaG10.ATAQUE;
						jugada[0] = i;
						jugada[1] = j;
						
					}
					else if(defensa > max && !(max>=3000 && (tipo == TipoJugadaG10.ATAQUE))){
						max = defensa;
						tipo = TipoJugadaG10.DEFENSA;
						jugada[0] = i;
						jugada[1] = j;
						
					}
					
					if(ataque>=3000){
						max = ataque;
						tipo = TipoJugadaG10.ATAQUE;
						jugada[0] = i;
						jugada[1] = j;
					
					}
				}
			}					
		}	
		return jugada;
	}
	
	/**Calculo de las ponderaciones cuando se simula una jugada de ataque	
	 * @param i
	 * @param j
	 * @param tablero
	 * @return
	 */
	private int getPonderacionAtaque(int i, int j, int[][] tablero){
		int ponderacion = 0;
		
		//Var�a la posici�n de la fila, revisando una columna
		int fichasFila = 0;
		//validacion jugada vertical
		if (isJugadaHorizontal(i, j, tablero, 1)) {
			for (int c = 1; i-c>=0 && c<4; c++) {
				if(tablero[i-c][j]==1){
					fichasFila++;
				}else{
					break;
				}
			}
			for (int c = 1; i+c<8 && c<4; c++) {
				if(tablero[i+c][j]==1){
					fichasFila++;
				}else{
					break;
				}
			}
			
		}
		
		//Var�a la posici�n de la Columna, revisando una fila
		int fichasColumna = 0;
		//validacion juagada horizontal
		if (isJugadaVertical(i, j, tablero, 1)) {
			for (int c = 1; j-c>=0 && c<4; c++) {
				if(tablero[i][j-c]==1){
					fichasColumna++;
				}else{
					break;
				}
			}
			for (int c = 1; j+c<8 && c<4; c++) {
				if(tablero[i][j+c]==1){
					fichasColumna++;
				}else{
					break;
				}
			}
			
			
		}
		
		//Diagonal1
		int fichasDiagonal1 = 0;
		//validacion juagada diagona uno
		if (isJugadaDiagonalUno(i, j, tablero, 1)) {
			for (int c = 1; i-c>=0 && j-c>=0 && c<4; c++) {
				if(tablero[i-c][j-c]==1){
					fichasDiagonal1++;
				}else{
					break;
				}
			}
			for (int c = 1; i+c<8 && j+c<8 && c<4; c++) {
				if(tablero[i+c][j+c]==1){
					fichasDiagonal1++;
				}else{
					break;
				}
			}
			
		}
		
		//Diagonal2
		int fichasDiagonal2 = 0;
		//validacion juagada diagona dos
		if (isJugadaDiagonalDos(i, j, tablero, 1)) {
			for (int c = 1; i-c>=0 && j+c<8 && c<4; c++) {
				if(tablero[i-c][j+c]==1){
					fichasDiagonal2++;
				}else{
					break;
				}
			}
			for (int c = 1; i+c<8 && j-c>=0 && c<4; c++) {
				if(tablero[i+c][j-c]==1){
					fichasDiagonal2++;
				}else{
					break;
				}
			}
		}
		
		ponderacion = PonderacionG10.ponderar(fichasColumna)+
						PonderacionG10.ponderar(fichasFila)+
						PonderacionG10.ponderar(fichasDiagonal1)+
						PonderacionG10.ponderar(fichasDiagonal2);
		return ponderacion;
	}
	
	/**Calculo de las ponderaciones cuando se simula una jugada de defensa
	 * @param i
	 * @param j
	 * @param tablero
	 * @return
	 */
	private int getPonderacionDefensa(int i, int j, int[][] tablero){
		int ponderacion = 0;
		
		//Var�a la posici�n de la fila, revisando una columna
		int fichasFila = 0;
		//validacion juagada vertical
		if (isJugadaHorizontal(i, j, tablero, 2)) {
			for (int c = 1; i-c>=0 && c<4; c++) {
				if(tablero[i-c][j]==2){
					fichasFila++;
				}else{
					break;
				}
			}
			for (int c = 1; i+c<8 && c<4; c++) {
				if(tablero[i+c][j]==2){
					fichasFila++;
				}else{
					break;
				}
			}
		}
		
		//Var�a la posici�n de la Columna, revisando una fila
		int fichasColumna = 0;
		//validacion juagada horizontal
		if (isJugadaVertical(i, j, tablero, 2)) {
			for (int c = 1; j-c>=0 && c<4; c++) {
				if(tablero[i][j-c]==2){
					fichasColumna++;
				}else{
					break;
				}
			}
			for (int c = 1; j+c<8 && c<4; c++) {
				if(tablero[i][j+c]==2){
					fichasColumna++;
				}else{
					break;
				}
			}
		}
		
		//Diagonal1
		int fichasDiagonal1= 0;
		//validacion juagada diagona uno
		if (isJugadaDiagonalUno(i, j, tablero, 2)) {
			for (int c = 1; i-c>=0 && j-c>=0 && c<4; c++) {
				if(tablero[i-c][j-c]==2){
					fichasDiagonal1++;
				}else{
					break;
				}
			}
			for (int c = 1; i+c<8 && j+c<8 && c<4; c++) {
				if(tablero[i+c][j+c]==2){
					fichasDiagonal1++;
				}else{
					break;
				}
			}
		}
		
		//Diagonal2
		int fichasDiagonal2= 0;
		//validacion juagada diagona dos
		if (isJugadaDiagonalDos(i, j, tablero, 2)) {
			for (int c = 1; i-c>=0 && j+c<8 && c<4; c++) {
				if(tablero[i-c][j+c]==2){
					fichasDiagonal2++;
				}else{
					break;
				}
			}
			for (int c = 1; i+c<8 && j-c>=0 && c<4; c++) {
				if(tablero[i+c][j-c]==2){
					fichasDiagonal2++;
				}else{
					break;
				}
			}
		}
		
		ponderacion = PonderacionG10.ponderar(fichasColumna)+
						PonderacionG10.ponderar(fichasFila)+
						PonderacionG10.ponderar(fichasDiagonal1)+
						PonderacionG10.ponderar(fichasDiagonal2);
		return ponderacion;
	}
	
	/**comprobar jugada vertical, haciendo variar la componente horizontal
	 * @param i
	 * @param j
	 * @param tablero
	 * @param op
	 * @return
	 */
	private boolean isJugadaHorizontal (int i, int j, int [][]tablero, int op) {		
		if (i-3>=0) {
			int lineaCuatro [] = {tablero[i-3][j], tablero[i-2][j], tablero[i-1][j], tablero[i][j]};
			if (isValido (lineaCuatro, op))	return true;
		}
		if (i-2>=0 && i+1<=7) {
			int lineaCuatro [] = {tablero[i-2][j], tablero[i-1][j], tablero[i][j], tablero[i+1][j]};
			if (isValido (lineaCuatro, op))	return true;
		}
		if (i-1>=0 && i+2<=7) {
			int lineaCuatro [] = {tablero[i-1][j], tablero[i][j], tablero[i+1][j], tablero[i+2][j]};
			if (isValido (lineaCuatro, op)) return true;
		}
		if (i+3<=7) {
			int lineaCuatro [] = {tablero[i][j], tablero[i+1][j], tablero[i+2][j], tablero[i+3][j]};
			if (isValido (lineaCuatro, op)) return true;
		}
		return false;
	}
	
	/**comprobar jugada horizontal, haciendo variar la componente vertical
	 * @param i
	 * @param j
	 * @param tablero
	 * @param op
	 * @return
	 */
	private boolean isJugadaVertical (int i, int j, int [][]tablero, int op) {
		if (j-3>=0) {
			int lineaCuatro [] = {tablero[i][j-3], tablero[i][j-2], tablero[i][j-1], tablero[i][j]};
			if (isValido (lineaCuatro, op))	return true;
		}
		if (j-2>=0 && j+1<=7) {
			int lineaCuatro [] = {tablero[i][j-2], tablero[i][j-1], tablero[i][j], tablero[i][j+1]};
			if (isValido (lineaCuatro, op))	return true;
		}
		if (j-1>=0 && j+2<=7) {
			int lineaCuatro [] = {tablero[i][j-1], tablero[i][j], tablero[i][j+1], tablero[i][j+2]};
			if (isValido (lineaCuatro, op)) return true;
		}
		if (j+3<=7) {
			int lineaCuatro [] = {tablero[i][j], tablero[i][j+1], tablero[i][j+2], tablero[i][j+3]};
			if (isValido (lineaCuatro, op)) return true;
		}
		return false;
	}
	
	/**comprobar jugada diagonal primaria
	 * @param i
	 * @param j
	 * @param tablero
	 * @param op
	 * @return
	 */
	private boolean isJugadaDiagonalUno (int i, int j, int [][]tablero, int op) {
		if (i-3>=0 && j-3>=0) {
			int lineaCuatro [] = {tablero[i-3][j-3], tablero[i-2][j-2], tablero[i-1][j-1], tablero[i][j]};
			if (isValido (lineaCuatro, op))	return true;
		}
		if (i-2>=0 && j-2>=0 && i+1<=7 && j+1<=7) {
			int lineaCuatro [] = {tablero[i-2][j-2], tablero[i-1][j-1], tablero[i][j], tablero[i+1][j+1]};
			if (isValido (lineaCuatro, op))	return true;
		}
		if (i-1>=0 && j-1>=0 && i+2<=7 && j+2<=7) {
			int lineaCuatro [] = {tablero[i-1][j-1], tablero[i][j], tablero[i+1][j+1], tablero[i+2][j+2]};
			if (isValido (lineaCuatro, op)) return true;
		}
		if (i+3<=7 && j+3<=7) {
			int lineaCuatro [] = {tablero[i][j], tablero[i+1][j+1], tablero[i+2][j+2], tablero[i+3][j+3]};
			if (isValido (lineaCuatro, op)) return true;
		}
		return false;
	}
	
	/**comprobar jugada diagonal secundaria
	 * @param i
	 * @param j
	 * @param tablero
	 * @param op
	 * @return
	 */
	private boolean isJugadaDiagonalDos (int i, int j, int [][]tablero, int op) {
		if (i+3<=7 && j-3>=0) {
			int lineaCuatro [] = {tablero[i+3][j-3], tablero[i+2][j-2], tablero[i+1][j-1], tablero[i][j]};
			if (isValido (lineaCuatro, op))	return true;
		}
		if (i+2<=7 && j-2>=0 && i-1>=0 && j+1<=7) {
			int lineaCuatro [] = {tablero[i+2][j-2], tablero[i+1][j-1], tablero[i][j], tablero[i-1][j+1]};
			if (isValido (lineaCuatro, op))	return true;
		}
		if (i+1<=7 && j-1>=0 && i-2>=0 && j+2<=7) {
			int lineaCuatro [] = {tablero[i+1][j-1], tablero[i][j], tablero[i-1][j+1], tablero[i-2][j+2]};
			if (isValido (lineaCuatro, op)) return true;
		}
		if (i-3>=0 && j+3<=7) {
			int lineaCuatro [] = {tablero[i][j], tablero[i-1][j+1], tablero[i-2][j+2], tablero[i-3][j+3]};
			if (isValido (lineaCuatro, op)) return true;
		}
		return false;
	}
	
	/**valida si en los cuatro lugares elegidos es conveniente realizar una jugada 
	 * @param linea
	 * @param op - 1:ataque, 2:defenza
	 * @return
	 */
	private boolean isValido (int linea [], int op) {
		int suma = 0;
		for (int r=0; r<linea.length; r++){
			suma = suma + (linea [r]*linea[r]);
			
		}
		switch (op) {
		case 1:
			if (suma<4) return true; //puedo atacar?
			break;
		case 2:
			if (suma>=4) return true; //puedo defender?
			break;
		}
		return false;		
	}
	
}

